package com.koron.standard.orderCard.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koron.bean.base.Attachment;
import com.koron.bean.base.Response;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.DisposeBeanUtil;
import com.koron.standard.bean.query.PageQuery;
import com.koron.standard.orderCard.bean.OrderCard;
import com.koron.standard.orderCard.bean.OrderCardFile;
import com.koron.standard.orderCard.bean.OrderCardQuery;
import com.koron.standard.orderCard.bean.StepBean;
import com.koron.standard.orderCard.config.OrderCardConfig;
import com.koron.standard.orderCard.feign.AttachmentFeignService;
import com.koron.standard.orderCard.mapper.OrderCardMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderCardServiceWarpper extends ServiceImpl<OrderCardMapper, OrderCard> {

	@Autowired
	private AttachmentFeignService attachmentFeignService;

	public Page<OrderCard> queryOrderCard(OrderCardQuery orderCardQuery, PageQuery<OrderCard> pageQuery, Integer isPage) {
		QueryWrapper<OrderCard> wrapper = new QueryWrapper<>();
		List<String> typeIds = new ArrayList<>();
		//提供不选设备类型的接口,但如果传回了设备id,则查询所有设备及其子节点下的工卡
		if (StringUtils.isNotBlank(orderCardQuery.getEquipmentTypeId())) {
			String typeLevel = getBaseMapper().getLevelByType(orderCardQuery.getEquipmentTypeId());
			Assert.isTrue(StringUtils.isNotBlank(typeLevel), "设备类型错误,没有该类型id");
			//获取设备与其子设备
			typeIds.addAll(getBaseMapper().queryTypeByLevel(typeLevel));
			typeIds.add(orderCardQuery.getEquipmentTypeId());
		}
		wrapper.eq("c_order_card.delete_flag",0);
		wrapper.ge(orderCardQuery.getCreateStartTime() != null, "c_order_card.create_time", orderCardQuery.getCreateStartTime());
		wrapper.le(orderCardQuery.getCreateEndTime() != null, "c_order_card.create_time", orderCardQuery.getCreateEndTime());
		wrapper.in(!CollectionUtils.isEmpty(typeIds),"c_order_card.equipment_type_id",typeIds);
		wrapper.like(StringUtils.isNotBlank(orderCardQuery.getCardName()),"c_order_card.card_name",orderCardQuery.getCardName());
		wrapper.like(StringUtils.isNotBlank(orderCardQuery.getCardCode()),"c_order_card.card_code",orderCardQuery.getCardCode());
		wrapper.like(StringUtils.isNotBlank(orderCardQuery.getEquipmentType()),"c_order_card.equipment_type",orderCardQuery.getEquipmentType());
		wrapper.eq(StringUtils.isNotBlank(orderCardQuery.getStatus()),"c_order_card.status",orderCardQuery.getStatus());
		Page<OrderCard> page = pageQuery.convertPage();
		getBaseMapper().queryOrderCardPage(page,wrapper);
		return page;
	}

	public OrderCard getOrderCardById(String id, String code) {
		//1,先获取到工单的基本信息,根据工卡id或code
		Assert.isTrue(!StringUtils.isAllBlank(id, code), "id,code不能同时为空");
		OrderCard orderCard = getBaseMapper().getOrderCardById(id, code);
		Assert.notNull(orderCard, "工卡不存在");

		//2,通过工单id,步骤id获取到所有附件,避免多次查询
		List<String> ids = new ArrayList<>();
		ids.addAll(orderCard.getStepList().stream().map(StepBean::getId).distinct().collect(Collectors.toList()));
		ids.add(orderCard.getId());

		//2.5 通过id获取附件
		ArrayList attachments = (ArrayList) attachmentFeignService.getAttachmentListByBusinessIdsWithType(ids.toArray(new String[ids.size()]), null).getData();
		attachments = CollectionUtils.isEmpty(attachments) ? new ArrayList<>() : attachments;

		// 获取附件映射
		// List<OrderCardFile> attachments = getBaseMapper().getOrderCardFileListByBusinessIds(ids);

		//3,对工单的三组附件列表和步骤列表里面的附件列表分别对应赋值
		//工单附件比较特殊,先用临时变量存储,再统一设置
		List<StepBean> steps = orderCard.getStepList().stream().sorted(Comparator.comparingInt(StepBean::getSort)).collect(Collectors.toList());
		Map<String, List<Attachment>> orderCardAttachment = new HashMap<>();
		// Map<String, List<OrderCardFile>> orderCardAttachment = new HashMap<>();
		orderCardAttachment.put(OrderCardConfig.AttachmentType.MANUALFILES, new ArrayList<>());
		orderCardAttachment.put(OrderCardConfig.AttachmentType.DRAWFILES, new ArrayList<>());
		orderCardAttachment.put(OrderCardConfig.AttachmentType.MODELFILES, new ArrayList<>());
		//3.5 根据card_step_id将附件与工卡和步骤对应
		String orderCardId = orderCard.getId();
		attachments.forEach(item -> {
			Attachment attachment = JSON.parseObject(JSON.toJSONString(item), Attachment.class);
			// 如果附件是工卡的附件类型,则放到对应map的key下
			if (attachment.getBusinessId().equals(orderCardId) && StringUtils.isBlank(attachment.getSubBusinessId())) {
				orderCardAttachment.get(attachment.getType()).add(attachment);
			}
			steps.forEach(step -> {
				if (attachment.getBusinessId().equals(step.getId())) {
					// 如果是步骤附件类型,按id区分不同步骤附件
					if (step.getFileList() == null) step.setFileList(new ArrayList<>());
					step.getFileList().add(attachment);
				}
			});
		});
		//分别工卡中设置三种不同附件列表
		orderCard.setManualFiles(orderCardAttachment.get(OrderCardConfig.AttachmentType.MANUALFILES));
		orderCard.setDrawFiles(orderCardAttachment.get(OrderCardConfig.AttachmentType.DRAWFILES));
		orderCard.setModelFiles(orderCardAttachment.get(OrderCardConfig.AttachmentType.MODELFILES));
		return orderCard;
	}

	public List<OrderCard> queryByTypeId(String typeId) {
		//根据设备id获取设备类型id
		Assert.isTrue(StringUtils.isNotBlank(typeId), "该工单不存在设备id");
/*		//这是设备唯一工卡的情况
		OrderCard orderCard = new OrderCard();
		orderCard.setEquipmentTypeId(equipmentTypeId);
		//调用接口获取工卡配置
		return getOrderCardById(factory,orderCard);*/
		return getBaseMapper().queryByEquipmentType(typeId,null,OrderCardConfig.OrderCardState.FINISH);
	}

	public Response saveOrUpdateOrderCard(OrderCard orderCard) {
		//如果调用接口时已经设置了id或者code,需要检查id或者code是否正确
		if (!StringUtils.isAllBlank(orderCard.getId(), orderCard.getCardCode())) {
			Assert.isTrue(getBaseMapper().getOrderCardById(orderCard.getId(), orderCard.getCardCode()) != null, "id由系统生成,不能独自设定");
		}
		//1,如果是提交,需要检测关键信息是否为空,并设置工卡状态
		if (orderCard.getSubmit()) {
			Assert.notNull(orderCard.getCardName(), "工卡名称不能为空");
			Assert.notNull(orderCard.getEquipmentTypeId(), "设备类型不能为空");
			orderCard.setStatus(OrderCardConfig.OrderCardState.FINISH);
			//相同设备类型工卡名不能相同
			List<OrderCard> orderCards = getBaseMapper().queryByEquipmentType(orderCard.getEquipmentTypeId(),orderCard.getCardName(),orderCard.getStatus());
			orderCards.forEach(item -> {
				Assert.isTrue(orderCard.getId().equals(item.getId()), "该设备类型已有相同工卡名称");
			});
		} else {
			orderCard.setStatus(OrderCardConfig.OrderCardState.DRAFT);
		}

		//2.1先存主表
		//首先分配一个工卡id,code,delete_flag,并保存基本信息(主表,步骤关联表,工具关联表)
		DisposeBeanUtil.dispose(ThreadLocalContext.get(), orderCard);
		orderCard.setId(StringUtils.isBlank(orderCard.getId()) ? CodeTools.getCode32() : orderCard.getId());
		orderCard.setCardCode(StringUtils.isBlank(orderCard.getCardCode()) ? CodeTools.getCodeNo(OrderCardConfig.prefix, 3) : orderCard.getCardCode());

		Assert.isTrue(getBaseMapper().saveOrUpdateOrderCard(orderCard) > 0, "保存失败!");

		//2.2再存步骤关联表
		//先把id,关联列,排序设置好
		// TODO 和前端对接一下，看是传新增的还是全传，传新增的这里就直接保存，全传就只能新增或更新，不管哪种删除都得单独实现

		List<OrderCardFile> stepFiles = new ArrayList<>();
		if (!CollectionUtils.isEmpty(orderCard.getStepList())) {
			orderCard.getStepList().forEach(step -> {
				step.setId(StringUtils.isBlank(step.getId()) ? CodeTools.getCode32() : step.getId());
				step.setOrderCardId(orderCard.getId());
				step.setCode(StringUtils.isBlank(step.getCode()) ? CodeTools.getCodeNo(OrderCardConfig.prefix_step, 3) : step.getCode());
				step.setSort(orderCard.getStepList().indexOf(step));
				// stepFiles.addAll(step.getFileList());
			});
/*			stepFiles.forEach(stepFile->{
				stepFile.setId(StringUtils.isBlank(stepFile.getId()) ? CodeTools.getCode32() : stepFile.getId());
			});
			getBaseMapper().saveOrUpdateFiles(stepFiles);*/
			Assert.isTrue(getBaseMapper().saveOrUpdateStepList(orderCard.getStepList()) > 0, "步骤保存失败!");
		}
		//2.3再然后存工具关联表
		if (!CollectionUtils.isEmpty(orderCard.getToolList())) {
			orderCard.getToolList().forEach(tool -> {
				Assert.isTrue(StringUtils.isNotBlank(tool.getName()) && StringUtils.isNotBlank(tool.getSpec()), "工具名和规格不能为空");
				tool.setId(StringUtils.isBlank(tool.getId()) ? CodeTools.getCode32() : tool.getId());
				tool.setCode(StringUtils.isBlank(tool.getCode()) ? CodeTools.getCodeNo(OrderCardConfig.prefix_tool, 3) : tool.getCode());
				tool.setOrderCardId(orderCard.getId());
			});
			Assert.isTrue(getBaseMapper().saveOrUpdateToolList(orderCard.getToolList()) > 0, "工器具保存失败!");
		}
		return Response.ok(orderCard.getId());
	}

	public Response deleteToolById(List<String> toolIds) {
		if (CollectionUtils.isEmpty(toolIds))
			return Response.ok();
		Assert.isTrue(getBaseMapper().deleteToolById(toolIds) > 0, "删除失败,id不存在!");
		return Response.success("删除成功");
	}

	public Response deleteStepById(List<String> stepIds) {
		if (CollectionUtils.isEmpty(stepIds))
			return Response.ok();
		getBaseMapper().deleteStepById(stepIds);
		return Response.success("删除成功");
	}

	public Response deleteOrderCardById(String orderCardId) {
		Assert.isTrue(StringUtils.isNotBlank(orderCardId), "id不能为空");
		Assert.isTrue(getBaseMapper().deleteOrderCardById(orderCardId) == 1, "删除失败,id不存在!");
		return Response.success("删除成功");
	}

	public Response deleteSingleFileById(String id){
		if (StringUtils.isEmpty(id))
			return Response.ok();
		Assert.isTrue(getBaseMapper().deleteSingleFileById(id) == 1, "删除失败，id不存在");
		return Response.success("删除成功");
	}

	public Response deleteFilesById(List<String> ids){
		if (CollectionUtils.isEmpty(ids))
			return Response.ok();
		Assert.isTrue(getBaseMapper().deleteFilesById(ids) > 1, "删除失败，id不存在");
		return Response.success("删除成功");
	}
}
